import JSON5 from 'json5'
import { applyEdits, format } from 'jsonc-parser'

// 去除首尾指定字符串
export function mixTrim(str: string, char: string) {
  if (char)
    str = str.replace(new RegExp(`^\\${char}+|\\${char}+$`, 'g'), '')

  return str.replace(/^\s+|\s+$/g, '')
}

// 获取富文本编辑器 文本内容
export function getRichText(htmlString: string) {
  if (!htmlString) {
    return htmlString
  }

  // 这个正则表达式会匹配所有的非HTML标签内容
  const regex = /<[^>]*>?/g // 匹配<tag>和</tag>，包括属性
  let text = htmlString.replace(regex, '') // 用空字符串替换所有的标签

  // 去除多余的空白字符（可选）
  // 注意：这种方法可能无法正确处理HTML实体，如&nbsp;
  text = text.replace(/\s+/g, ' ').trim() // 将所有连续的空白字符替换为一个空格，并去除首尾空白

  return text
}

/**
 * 生成指定长度随机字符串
 * @param length
 */
export function randomString(length: number = 8) {
  const chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
  let result = ''
  for (let i = 0; i < length; i++) {
    result += chars[Math.floor(Math.random() * chars.length)]
  }
  return result
}

/**
 * 校验字符串是否为数组字符串
 * @param str
 */
export function isArrayString(str: string) {
  try {
    const parsed = JSON.parse(str)
    // 校验是否是一个数组
    return Array.isArray(parsed)
  }
  // eslint-disable-next-line unused-imports/no-unused-vars
  catch (e) {
    // 如果解析失败，则认为不是有效的JSON数组字符串
    return false
  }
}

/**
 * 校验字符串是否为JSON字符串
 * @param str
 */
export function isJsonString(str: string) {
  try {
    // eslint-disable-next-line unused-imports/no-unused-vars
    const parsed = JSON.parse(str)
    // 校验是否是一个数组
    return true
  }
  // eslint-disable-next-line unused-imports/no-unused-vars
  catch (e) {
    // 如果解析失败，则认为不是有效的JSON数组字符串
    return false
  }
}

/**
 * 校验字符串是否为JSON5字符串
 * @param str
 */
export function isJson5String(str: string) {
  try {
    // eslint-disable-next-line unused-imports/no-unused-vars
    const parsed = JSON5.parse(str)
    // 校验是否是一个数组
    return true
  }
  // eslint-disable-next-line unused-imports/no-unused-vars
  catch (e) {
    // 如果解析失败，则认为不是有效的JSON数组字符串
    return false
  }
}

/**
 * 格式化json5
 * @param str
 */
export function formattedJson5(str: string) {
  try {
    // 1. 解析 JSON5 字符串，获取 AST

    // 2. 使用 format API 进行格式化
    const formattedEdits = format(str, undefined, {
      tabSize: 2,
      insertSpaces: true,
      eol: '\n',
    })

    // 3. 应用格式化修改，重新生成字符串
    return applyEdits(str, formattedEdits)
  }
  // eslint-disable-next-line unused-imports/no-unused-vars
  catch (e) {
    // 如果解析失败，则直接返回
    return str
  }
}

/**
 * 生成 min 到 max 之间的随机整数
 * @param min
 * @param max
 */

export function getRandomIntInclusive(min: number, max: number) {
  min = Math.ceil(min)
  max = Math.floor(max)
  return Math.floor(Math.random() * (max - min + 1)) + min // 最大值和最小值都包含
}

/**
 * 获取url的协议
 * @param url
 */
export function getUrlProtocol(url: string) {
  try {
    const urlObj = new URL(url)
    return `${urlObj.protocol}//` // 补全为 "http://" 或 "https://"
  }
  catch (e: any) {
    // eslint-disable-next-line no-console
    console.log(e)
    return null // URL 不合法或缺少协议
  }
}

/**
 * 从响应头的ContentDisposition中获取文件名称
 * @param contentDis
 */
export function getFilenameFromContentDis(contentDis: string) {
  // 正则表达式匹配 filename 参数，处理带引号和不带引号的情况
  const regex = /filename\s*=\s*(?:"([^"]*)"|([^;\r\n]*))/i
  const match = contentDis.match(regex)

  if (!match)
    return null

  // 优先取带引号的匹配结果，否则取不带引号的
  const filename = match[1] || match[2]

  // 去除路径符号（可选，根据需求调整）
  return filename.replace(/^.*[\\/]/, '')
}

/**
 * 返回元素名称非空数据
 * @param list
 */
export function filterBlankName(list: Array<any>) {
  return list.filter((item: any) => item.name)
}

/**
 * 判断字符串是否是数字
 * @param str
 */
export function isNumber(str: string) {
  return !Number.isNaN(Number(str)) && str.trim() !== ''
}

/**
 * 获取域名
 * @param location
 */
export function getDomain(location: any): string {
  // 获取最后两个部分（假设顶级域名由两部分组成）
  const hostname = location.hostname
  const reg = /^(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})$/
  let domain = hostname
  if (!reg.test(hostname)) {
    const domainArr = hostname.split('.')
    domain = `.${domainArr[domainArr.length - 2]}.${domainArr[domainArr.length - 1]}`
  }
  return domain
}
